package cn.com.sparkle.paxos.addprocess.speedcontrol;

import org.apache.log4j.Logger;

import com.google.protobuf.ByteString;

import cn.com.sparkle.paxos.Configuration;
import cn.com.sparkle.paxos.event.EventsManager;
import cn.com.sparkle.paxos.event.InstanceExecuteMaxPackageSizeEvent;
import cn.com.sparkle.paxos.event.InstancePaxosEvent;
import cn.com.sparkle.paxos.event.SpeedControlEvent;
//import cn.com.sparkle.paxos.model.Id;
//import cn.com.sparkle.paxos.model.Value;
import cn.com.sparkle.paxos.iomodel.protobuffmessage.PaxosMessages.Value;
import cn.com.sparkle.paxos.paxosinstance.InstancePaxosInstance;
import cn.com.sparkle.paxos.iomodel.protobuffmessage.PaxosMessages.Id;

public class SpeedControlModel {
	private final static Logger logger = Logger
			.getLogger(SpeedControlModel.class);

	private int curTcpPackageSize;

	public SpeedControlModel(final EventsManager eventsManger,
			final Configuration conf) {
		eventsManger.registerEvent(new InstancePaxosEvent() {
			@Override
			public void success(InstancePaxosInstance instance, Value value) {
				int valueSize = 0;
				for (ByteString bs : value.getValuesList()) {
					valueSize += bs.size();
				}
				logger.debug("valuesize:" + valueSize);
				if (System.currentTimeMillis() - instance.getStartTime() < conf
						.getResponseDelay()) {
					int promoteSize = valueSize * 2;
					logger.debug("up promoteSize :" + promoteSize
							+ " curTcpPackageSize:" + curTcpPackageSize);
					if (promoteSize > curTcpPackageSize) {
						SpeedControlEvent.doSuggestMaxPackageSizeEvent(
								eventsManger, promoteSize);
					}
				} else {
					int promoteSize = (int) Math.floor(valueSize * 0.75);
					logger.debug("down promoteSize :" + promoteSize
							+ " curTcpPackageSize:" + curTcpPackageSize);
					if (promoteSize < curTcpPackageSize) {
						SpeedControlEvent.doSuggestMaxPackageSizeEvent(
								eventsManger, promoteSize);
					}
				}
			}

			@Override
			public void start(InstancePaxosInstance instance) {
			}

			@Override
			public void fail(InstancePaxosInstance instance, Id.Builder id,
					long refuseId) {
			}
		});
		eventsManger.registerEvent(new InstanceExecuteMaxPackageSizeEvent() {
			@Override
			public void maxPackageSizeChange(int curMaxPackageSize) {
				curTcpPackageSize = curMaxPackageSize;
				logger.debug("maxPackageSizeChange cur value="
						+ curMaxPackageSize);
			}
		});
	}

}
